package com.hengfoxwolf.jetpackdemo.defineview
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.get
import com.hengfoxwolf.jetpackdemo.R

class FloatLayout @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : ConstraintLayout(context, attributeSet) {

    private var downX = 0
    private var downY = 0
    private var movedX = 0
    private var movedY = 0

    private var maxMovedX = 0
    private var maxMovedY = 0

    private var redundantHeight = 0

    private var doInit = true

    private val rect = Rect()

    init {
        val view = LayoutInflater.from(context).inflate(R.layout.layout_flow_ball, this, false)
        addView(
            view,
            LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT
            )
        )

        with(context.obtainStyledAttributes(attributeSet,R.styleable.FloatLayout)) {
            redundantHeight = getDimension(R.styleable.FloatLayout_redundantHeight,0F).toInt()
            recycle()
        }

        movedX = resources.displayMetrics.widthPixels
        movedY = resources.displayMetrics.heightPixels * 5 / 7
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        for (i in 0.until(childCount)) {
            val child = get(i)
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0)
        }
        setMeasuredDimension(
            MeasureSpec.getSize(widthMeasureSpec) - paddingStart - paddingEnd,
            MeasureSpec.getSize(heightMeasureSpec) - paddingTop - paddingBottom
        )
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)

        val view = get(0)
        val layoutParams = view.layoutParams as LayoutParams
        val l = layoutParams.marginStart
        val r = view.measuredWidth + layoutParams.marginStart
        val t = layoutParams.topMargin
        val b = t + view.measuredHeight

        maxMovedX = right - left - view.measuredWidth - layoutParams.rightMargin
        maxMovedY = bottom - top - view.measuredHeight - layoutParams.bottomMargin - redundantHeight

        movedX = Math.max(Math.min(movedX, maxMovedX), 0)
        movedY = Math.max(Math.min(movedY, maxMovedY), 0)

        view.layout(l + movedX, t + movedY, r + movedX, b + movedY)

        val rectL = l + movedX
        val rectT = t + movedY
        val rectR = rectL + view.measuredWidth
        val rectB = rectT + view.measuredHeight
        rect.set(rectL, rectT, rectR, rectB)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                downY = ev.y.toInt()
            }
            MotionEvent.ACTION_MOVE -> {
                val actionMoveY = ev.y.toInt()
                if (rect.contains(ev.x.toInt(), actionMoveY)) {
                    //在这里返回false才会处理子view点击事件
                    return Math.abs(actionMoveY - downY) >= MIN_SLIDE_DISTANCE
                }
                downY = actionMoveY
            }
            MotionEvent.ACTION_UP -> {}
        }
        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        performClick()
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d(TAG, "onTouchEvent->MotionEvent.ACTION_DOWN")
                return if (rect.contains(event.x.toInt(), event.y.toInt())) {
                    downX = event.x.toInt()
                    downY = event.y.toInt()
                    true
                } else {
                    super.onTouchEvent(event)
                }
            }
            MotionEvent.ACTION_MOVE -> {
                val actionMoveX = event.x.toInt()
                val actionMoveY = event.y.toInt()
                Log.d(TAG, "onTouchEvent->MotionEvent.ACTION_MOVE")
                val movedDiffXValue = actionMoveX - downX
                val movedDiffYValue = actionMoveY - downY
                movedX += movedDiffXValue
                movedY += movedDiffYValue
                requestLayout()
                downX = actionMoveX
                downY = actionMoveY
            }
            MotionEvent.ACTION_UP -> {
                Log.d(TAG, "onTouchEvent->MotionEvent.ACTION_UP")
            }
        }
        return super.onTouchEvent(event)
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }

    companion object {
        const val TAG = "FloatLayout"
        //最小滑动距离
        const val MIN_SLIDE_DISTANCE = 5
    }
}